// chatService.js
// 负责处理API调用，发送消息和接收回复
// 该文件已优化，支持多种API提供商的格式，包括OpenAI、SophNet、MiniMax、阿里云等

import axios from 'axios';

// 设置后端API基础URL
const API_BASE_URL = '/backend'; // 可以根据实际部署情况修改

/**
 * 聊天服务类，处理与AI API的通信
 */
class ChatService {
  /**
   * 发送消息到AI，获取回复
   * @param {number|string} apiKeyId - API密钥ID
   * @param {Array} messages - 消息历史，格式为[{role: 'user'|'assistant', content: '消息内容'}, ...]
   * @param {Function} onStreamData - 流式数据接收回调函数，参数为新收到的文本片段
   * @returns {Promise} - 返回AI回复的Promise
   */
  async sendMessage(apiKeyId, messages, onStreamData = null) {
    try {
      // 验证参数
      if (!apiKeyId) {
        throw new Error('API密钥ID不能为空');
      }

      if (!messages || !Array.isArray(messages) || messages.length === 0) {
        throw new Error('消息不能为空');
      }
      
      // 从localStorage获取API配置
      const apiConfigsStr = localStorage.getItem('apiConfigs');
      if (!apiConfigsStr) {
        throw new Error('未找到API配置，请先在设置中添加API配置');
      }
      
      const apiConfigs = JSON.parse(apiConfigsStr);
      const apiConfig = apiConfigs.find(config => config.id == apiKeyId);
      
      if (!apiConfig) {
        throw new Error(`未找到ID为 ${apiKeyId} 的API配置`);
      }
      
      // 清理并格式化endpoint
      let cleanEndpoint = apiConfig.endpoint.trim();
      let apiUrl;
      
      // 优化URL处理逻辑，提高兼容性
      console.log('处理API URL:', cleanEndpoint);
      
      // 1. 检查URL是否已经包含完整API路径
      const containsCompletePath = /\/(v1\/)?chat\/completions$|\/(v1\/)?text\/chat|\/(compatible-mode\/v1\/)?chat\/completions$|\/text\/chatcompletion_v2/.test(cleanEndpoint);
      const isSpecialAPI = ['minimax.chat', 'dashscope.aliyuncs.com', 'qianwen', 'claude', 'gemini'].some(api => cleanEndpoint.includes(api));
      
      // 2. 根据URL特征和结尾字符处理
      if (cleanEndpoint.endsWith('#')) {
        // #结尾: 强制使用输入地址（去掉#）
        apiUrl = cleanEndpoint.slice(0, -1);
        console.log('强制使用输入的完整API地址:', apiUrl);
      }
      else if (containsCompletePath || isSpecialAPI) {
        // 已包含完整路径或特殊API: 直接使用
        apiUrl = cleanEndpoint;
        console.log('检测到完整API路径或特殊API，使用原始URL:', apiUrl);
      }
      else if (cleanEndpoint.endsWith('/')) {
        // /结尾: 忽略v1版本路径，但仍然添加chat/completions
        apiUrl = `${cleanEndpoint}chat/completions`;
        console.log('使用自定义路径，忽略v1前缀:', apiUrl);
      }
      else {
        // 其他情况: 使用标准OpenAI路径格式
        // 如果endpoint不以/结尾，添加一个/
        if (!cleanEndpoint.endsWith('/')) {
          cleanEndpoint += '/';
        }
        apiUrl = `${cleanEndpoint}v1/chat/completions`;
        console.log('使用标准OpenAI路径格式:', apiUrl);
      }
      
      // 构建系统消息，要求模型先输出思维过程，再输出最终答案
      let hasSystemMessage = false;
      for (const msg of messages) {
        if (msg.role === 'system') {
          // 使用原有的系统消息，不添加额外指令
          hasSystemMessage = true;
          break;
        }
      }
      
      // 如果没有系统消息，添加一个基本的系统消息
      if (!hasSystemMessage) {
        messages.unshift({
          role: 'system',
          content: "你是AI助手，请尽可能提供有帮助的回答。"
        });
      }
      
      // 创建请求数据
      const requestData = {
        model: apiConfig.modelName || apiConfig.provider, // 优先使用modelName，如果不存在则使用provider
        messages: messages,
        temperature: 0.7,
        max_tokens: 2000,
        stream: !!onStreamData // 如果提供了回调函数，则启用流式模式
      };
      
      // 为不同API提供商添加特殊参数
      const isMiniMax = cleanEndpoint.includes('minimax.chat');
      const isAliyun = cleanEndpoint.includes('dashscope.aliyuncs.com');
      const isQianwen = cleanEndpoint.includes('qianwen');
      
      // MiniMax API特殊处理
      if (isMiniMax) {
        // minimax.chat需要特殊处理，调整请求参数
        console.log('正在配置MiniMax API特殊参数');
        
        // 检查endpoint完整路径以确定使用哪种API格式
        if (cleanEndpoint.includes('chatcompletion_v2')) {
          // 使用chatcompletion_v2接口的配置
          // 保持现有格式，添加特定参数
          requestData.bot_setting = [
            {
              bot_name: "Assistant",
              content: "You are an AI assistant."
            }
          ];
          // 其他MiniMax特定参数
          requestData.reply_constraints = {
            sender_type: "BOT",
            sender_name: "Assistant"
          };
        } else if (cleanEndpoint.includes('text/chat')) {
          // 为chat接口调整消息格式
          // 转换messages格式为MiniMax格式
          const miniMaxMessages = messages.map(msg => {
            if (msg.role === 'user') {
              return { sender_type: 'USER', sender_name: 'User', text: msg.content };
            } else if (msg.role === 'assistant') {
              return { sender_type: 'BOT', sender_name: 'Assistant', text: msg.content };
            } else if (msg.role === 'system') {
              return { sender_type: 'SYSTEM', text: msg.content };
            }
            return null;
          }).filter(msg => msg !== null);
          
          // 替换请求数据
          requestData.messages = miniMaxMessages;
          requestData.model = apiConfig.modelName || apiConfig.provider;
          requestData.prompt = ''; // 某些API需要空prompt
        }
      }
      // 阿里云API特殊处理
      else if (isAliyun || isQianwen) {
        console.log('正在配置阿里云/千问API参数');
        
        // 某些阿里云API需要的特殊参数
        if (!requestData.parameters) {
          requestData.parameters = {};
        }
        
        // 可能需要的结果格式参数
        requestData.result_format = "message";
        
        // 如果是compatible-mode，保持标准OpenAI格式
        if (cleanEndpoint.includes('compatible-mode')) {
          console.log('使用阿里云兼容模式，保持标准格式');
        }
      }
      
      // 创建请求配置
      const config = {
        headers: {
          'Authorization': `Bearer ${apiConfig.key}`,
          'Content-Type': 'application/json'
        },
        timeout: 60000, // 60秒超时
        ...(onStreamData ? { responseType: 'stream' } : {})
      };
      
      // 如果启用了流式模式
      if (onStreamData) {
        return new Promise(async (resolve, reject) => {
          try {
            // 使用fetch API来处理流
            const response = await fetch(apiUrl, {
              method: 'POST',
              headers: {
                'Authorization': `Bearer ${apiConfig.key}`,
                'Content-Type': 'application/json'
              },
              body: JSON.stringify(requestData)
            });
            
            if (!response.ok) {
              throw new Error(`API返回错误状态码: ${response.status}`);
            }
            
            // 确保响应体是可读流
            const reader = response.body.getReader();
            const decoder = new TextDecoder('utf-8');
            let fullText = '';
            let reasoningText = '';
            let contentText = '';
            
            // 用于临时存储未完整解析的行
            let buffer = '';
            
            console.log('开始流式接收数据...');
            
            // 循环读取流数据
            while (true) {
              const { done, value } = await reader.read();
              if (done) {
                console.log('流式响应结束');
                break;
              }
              
              // 将二进制数据转换为文本
              const chunk = decoder.decode(value, { stream: true });
              console.log('收到数据块:', chunk.length, '字节');
              if (chunk.trim()) {
                // 记录原始数据用于调试
                const maxLength = 200; // 限制日志长度
                console.log('原始数据:', chunk.length > maxLength 
                            ? chunk.substring(0, maxLength) + '...(已截断)' 
                            : chunk);
              }
              buffer += chunk;
              
              // 按行分割，处理完整的行
              const lines = buffer.split('\n');
              // 保留最后一个可能不完整的行
              buffer = lines.pop() || '';
              
              for (const line of lines) {
                if (line.trim() === '') continue; // 跳过空行
                
                if (line.startsWith('data:')) {
                  try {
                    // 去除前缀并解析JSON数据
                    const jsonStart = line.indexOf('{');
                    if (jsonStart === -1) {
                      // 没有JSON数据
                      console.log('行中没有JSON数据:', line);
                      continue;
                    }
                    
                    const jsonText = line.substring(jsonStart);
                    let jsonData;
                    try {
                      jsonData = JSON.parse(jsonText);
                    } catch (parseError) {
                      console.error('JSON解析失败:', parseError, '原始数据:', jsonText);
                      continue;
                    }
                    
                    // 处理不同的API响应格式
                    if (jsonData.choices && jsonData.choices.length > 0) {
                      const choice = jsonData.choices[0];
                      
                      // 处理SophNet风格的流式格式
                      if (jsonData.object === 'chat.completion.chunk') {
                        const delta = choice.delta;
                        
                        // 处理reasoning_content（思考过程）
                        if (delta.reasoning_content !== undefined) {
                          const reasoning = delta.reasoning_content || '';
                          reasoningText += reasoning;
                          onStreamData(reasoning, 'reasoning');
                          console.log('收到reasoning:', reasoning);
                        }
                        
                        // 处理content（最终回答内容）
                        if (delta.content !== undefined) {
                          const content = delta.content || '';
                          contentText += content;
                          onStreamData(content, 'content');
                          console.log('收到content:', content);
                        }
                      }
                      // 处理SophNet的流式格式
                      else if (choice.delta) {
                        const delta = choice.delta;
                        
                        // 处理content（最终回答内容）
                        if (delta.content !== undefined) {
                          const content = delta.content || '';
                          contentText += content;
                          onStreamData(content, 'content');
                          console.log('收到SophNet content:', content);
                        }
                      }
                      // 处理MiniMax格式的响应
                      else if (jsonData.reply || (choice && choice.text)) {
                        // MiniMax文本完成API可能直接返回reply字段
                        const content = jsonData.reply || choice.text || '';
                        if (content && content.trim() !== '') {
                          contentText += content;
                          onStreamData(content, 'content');
                          console.log('收到MiniMax直接回复:', content);
                        }
                      }
                      // 处理阿里云/通用格式响应
                      else if (choice.message && choice.message.content) {
                        const content = choice.message.content || '';
                        if (content && content.trim() !== '') {
                          contentText += content;
                          onStreamData(content, 'content');
                          console.log('收到阿里云/通用格式回复:', content);
                        }
                      }
                      // 处理阿里云千问的text响应格式
                      else if (choice.text || jsonData.output && jsonData.output.text) {
                        const content = choice.text || (jsonData.output && jsonData.output.text) || '';
                        if (content && content.trim() !== '') {
                          contentText += content;
                          onStreamData(content, 'content');
                          console.log('收到阿里云千问格式回复:', content);
                        }
                      }
                      // 处理最终的完整消息（通常是流的最后一个消息）
                      else if (jsonData.object === 'chat.completion') {
                        console.log('收到完整响应');
                        if (choice.message) {
                          const message = choice.message;
                          if (message.content && message.content.trim() !== '') {
                            // 如果之前没有收到任何内容，则将完整内容作为content处理
                            if (contentText === '' && reasoningText === '') {
                              contentText = message.content;
                              fullText = message.content;
                              onStreamData(message.content, 'content');
                              console.log('处理完整响应内容');
                            }
                          }
                        }
                      }
                      // 处理MiniMax格式的messages数组
                      else if (jsonData.choices && choice.messages) {
                        console.log('检测到MiniMax格式响应');
                        try {
                          // 查找assistant消息
                          const assistantMessage = choice.messages.find(m => m.role === 'assistant');
                          if (assistantMessage && assistantMessage.content) {
                            contentText += assistantMessage.content;
                            onStreamData(assistantMessage.content, 'content');
                            console.log('处理MiniMax内容:', assistantMessage.content);
                          }
                          
                          // 查找tool响应（可能包含reasoning）
                          const toolMessage = choice.messages.find(m => m.role === 'tool');
                          if (toolMessage && toolMessage.content) {
                            reasoningText += toolMessage.content;
                            onStreamData(toolMessage.content, 'reasoning');
                            console.log('处理MiniMax reasoning:', toolMessage.content);
                          }
                        } catch (e) {
                          console.error('处理MiniMax消息时出错:', e);
                        }
                      }
                    }
                    // 处理MiniMax/阿里云API的特殊响应格式
                    else if (jsonData.reply || jsonData.text || (jsonData.output && jsonData.output.text)) {
                      // 一些API直接返回reply、text或output.text字段
                      const content = jsonData.reply || jsonData.text || (jsonData.output && jsonData.output.text) || '';
                      if (content && content.trim() !== '') {
                        contentText += content;
                        onStreamData(content, 'content');
                        console.log('收到特殊格式回复:', content);
                      }
                    }
                  } catch (e) {
                    console.error('解析流数据时出错:', e, '原始数据:', line);
                  }
                } else if (line.includes('[DONE]')) {
                  // 流结束标记
                  console.log('接收到流结束标记');
                }
              }
            }
            
            // 处理可能剩余在buffer中的数据
            if (buffer.length > 0 && buffer.includes('{')) {
              try {
                const jsonText = buffer.substring(buffer.indexOf('{'));
                const jsonData = JSON.parse(jsonText);
                
                if (jsonData.choices && jsonData.choices.length > 0) {
                  const choice = jsonData.choices[0];
                  
                  if (jsonData.object === 'chat.completion.chunk') {
                    const delta = choice.delta;
                    if (delta.reasoning_content !== undefined) {
                      reasoningText += delta.reasoning_content;
                      onStreamData(delta.reasoning_content, 'reasoning');
                      console.log('缓冲区最后的reasoning:', delta.reasoning_content);
                    }
                    if (delta.content !== undefined) {
                      contentText += delta.content;
                      onStreamData(delta.content, 'content');
                      console.log('缓冲区最后的content:', delta.content);
                    }
                  } 
                  else if (jsonData.object === 'chat.completion') {
                    if (choice.message) {
                      const message = choice.message;
                      if (message.content && message.content.trim() !== '' && contentText === '' && reasoningText === '') {
                        contentText = message.content;
                        fullText = message.content;
                        onStreamData(message.content, 'content');
                        console.log('处理缓冲区最后的完整响应');
                      }
                    }
                  }
                }
              } catch (e) {
                console.error('解析缓冲区剩余数据时出错:', e, '原始数据:', buffer);
              }
            }
            
            // 返回成功结果和完整文本
            resolve({
              success: true,
              message: fullText,
              reasoning: reasoningText,
              content: contentText,
              isStreaming: true
            });
          } catch (error) {
            console.error('流式处理错误:', error);
            reject(error);
          }
        });
      } else {
        // 非流式模式，直接发送常规请求
        const response = await axios.post(apiUrl, requestData, config);
        
        if (response.status >= 200 && response.status < 300) {
          // 处理成功响应
          let responseContent = '';
          
          // 处理各种格式的响应
          if (response.data && response.data.choices && response.data.choices.length > 0) {
            const choice = response.data.choices[0];
            
            // 标准OpenAI格式
            if (choice.message && choice.message.content) {
              responseContent = choice.message.content;
            }
            // MiniMax格式
            else if (choice.text) {
              responseContent = choice.text;
            }
            // 处理messages数组格式
            else if (choice.messages) {
              const assistantMessage = choice.messages.find(m => m.role === 'assistant');
              if (assistantMessage && assistantMessage.content) {
                responseContent = assistantMessage.content;
              }
            }
          }
          // 处理直接返回reply或text的格式
          else if (response.data.reply || response.data.text) {
            responseContent = response.data.reply || response.data.text;
          }
          // 处理阿里云格式
          else if (response.data.output && response.data.output.text) {
            responseContent = response.data.output.text;
          }
          
          // 如果提取到响应内容
          if (responseContent) {
            return {
              success: true,
              message: responseContent,
              data: response.data
            };
          } else {
            console.warn('未能识别的API响应格式:', response.data);
            throw new Error('API响应格式异常');
          }
        } else {
          throw new Error(`API返回错误状态码: ${response.status}`);
        }
      }
    } catch (error) {
      console.error('API调用失败:', error);
      
      let errorMessage = '消息发送失败';
      
      // 提取更有用的错误信息
      if (error.response) {
        // 服务器返回了错误状态码
        const statusCode = error.response.status;
        
        if (statusCode === 400) {
          errorMessage = '请求参数错误';
        } else if (statusCode === 401) {
          errorMessage = 'API密钥无效或未授权';
        } else if (statusCode === 404) {
          errorMessage = '未找到API配置或服务不存在';
        } else if (statusCode === 429) {
          errorMessage = 'API请求次数超限或达到速率限制';
        } else if (statusCode >= 500) {
          errorMessage = '服务器内部错误';
        }
        
        // 尝试从错误响应中提取详细信息
        if (error.response.data && error.response.data.error) {
          if (typeof error.response.data.error === 'string') {
            errorMessage += `: ${error.response.data.error}`;
          } else if (error.response.data.error.message) {
            errorMessage += `: ${error.response.data.error.message}`;
          }
        }
      } else if (error.message) {
        errorMessage = error.message;
      }
      
      return {
        success: false,
        message: errorMessage
      };
    }
  }

  /**
   * 获取可用的API配置列表
   * @returns {Promise<Array>} - 返回API配置列表的Promise
   */
  async getApiConfigs() {
    try {
      // 从localStorage获取API配置，而不是从后端获取
      const apiConfigsStr = localStorage.getItem('apiConfigs');
      if (apiConfigsStr) {
        return JSON.parse(apiConfigsStr);
      }
      
      // 如果本地存储中没有数据，尝试从settings中获取
      // 这里我们需要创建一个空数组作为默认值
      return [];
      
      // 原有的从后端获取的代码已注释
      // const response = await axios.get(`${API_BASE_URL}/api-keys`);
      // return response.data;
    } catch (error) {
      console.error('获取API配置失败:', error);
      throw new Error('获取API配置失败: ' + (error.message || '未知错误'));
    }
  }
  
  /**
   * 保存API配置到本地存储
   * @param {Array} configs - API配置列表
   */
  saveApiConfigs(configs) {
    try {
      localStorage.setItem('apiConfigs', JSON.stringify(configs));
    } catch (error) {
      console.error('保存API配置失败:', error);
    }
  }
}

// 创建并导出聊天服务实例
const chatService = new ChatService();
export default chatService; 